I've set up a 2d array aligned to my terrain, the array is at most 1024 x 1024. I've then filled this array with the relevant leaf of my quadtree. So when I traverse the tree and either enable or disable parts of the tree for rendering the array effectively is updated at the same time, the tree pruning also culls static assets for those leaves. But, for dynamic assets that move, I use the 2d array to find out where they are if they need to be rendered. I am going to use this for my particle system too, to remove the particles that aren't on screen at that point in time. Sorting should be quicker.
As far as culling goes ... what I've got working is a simple sleeping mechanism
Each emitter has a uint sleep counter, while processing the particle system I do a min max on all points to generate a AABB.
The AABB is checked against the view frustum. If it's visible I reset the counter to zero... otherwise I increment.
If the counter is above lets say 30 I just stop updating it and wait for the last bounding box to become visible again before resuming.
This works well for environmental emitters (working on a waterfall at the moment) but other uses might need to time out destroy themselves.