And our management is quite a bit more complicated. For standard culling we hold multiple "scenegraphs" - for example:
Lights are handled using bounding volumes (we use AABBs for all lights right now - either "point", "spot" or "directional" - note that we only use area lights actually, so they have real size). This BVH is dynamically recomputed on the run.
Basically same goes for dynamic objects (we don't hold single one BVH here for all of them, but rather one for characters, one for dynamic objects, etc.). Also dynamically recomputed on the run, holds OBBs.
Static meshes are divided to high detail (cells you currently are at) and low detail (distant meshes). High detail is fairly simple, we hold pre-computed tree of the whole cell for culling. Low detail meshes are very tricky. We basically use them for distant view and for other effects (realtime reflections using ray tracing, dynamic global illumination, etc.), so we have precomputed KdTree for ray tracing. For distant view rendering, we use just simple quadtree to cull out invisible cells.
Note that all cells have same dimensions. And also that most things in our world(s) are dynamic. Basically this complicates stuff a lot, because we can't use things like SVO and cone tracing, we have to stick to in my opinion more accurate and better solutions.
As for culling - we perform simple frustum culling, occlusion culling is performed just for static objects right now (there weren't any real gains for dynamic objects, as you have them visible only in sorrounding cells and in specified radius - also they're pretty much LODded out mostly).
The current bottleneck is editing (apart from ray tracing, which eats a lot of performance - but reflections are reflections!), we have an editor that runs interactively "in game", although after editing we still have the ugly "precompute" button there to precompute distant meshes & static stuff.