If you ask 5 game developers you may well get 5 different solutions or overlapping answers. The system to go for depends a lot on the type of game and the environment you exist in. There's also the divide between offline and real-time solutions. There's also no reason why octree and BSP tree solutions aren't also still used in certain scenarios.
Personally, for what I've worked on (racing games) we've used a pre-calculated static visibility system where offline we divide the world up into a grid, then we move the camera around inside the grid cell checking to see what it can see at a fairly coarse level. What we end up with is for every cell we have a bit list which says which models definately are not visible to the camera from that location. Once in game, we can very quickly get a subset of the world from which we can frustum cull to work out what we actually need to render in front of the camera.
Another title here uses a combination of that and portals, where you effectively have a door through which you can determine if you can see whats on the other side. If you can't see the door, you don't need to worry what's on the other side.
A real-time system that I've seen used (but have no personal experience of) is dPVS, which performs occlusion testing in real-time (they've got a paper linked from their website on how it works).
It all depends on what you need, different systems also allow you trade a bit of extra memory for speed.