the obvious one is to have player positions determined fully by the client. just have the client send the update origin+angles and the server can omit all the traceboxes required to move the player through the world (this gives teleportation).
you could have the client telling the server that various monsters should become hostile when the player gets close (ie: the client does per-client/monster tracelines instead of the server) (this gives notarget).
you could have the client running full animation. this might cause slight de-syncs, but it shouldn't really be much worse than the server updating every frame individually.
if your idle monsters are meant to roam slightly around some tether point (to give a bit more life to your maps), have the monster's position as some monster.effectiveorigin = monster.roamcenter+CalcRoam(time*monster.roamspeed) function that the client+server are both using, preventing the need for resends. have the client determine angles too. this only really works for idle monsters though, but combined with the client reporting when monsters become hostile this removes ALL load of idle monsters from the server - its value is significant when you have lots of monsters which are too lazy to attack distant players.
you could have the client determine when the missiles the client fired impact upon walls/enemies(aimbot). may have issues when the target goes out of the pvs, but hey. Alternatively you can write your game to determine hit/miss when its first fired, and have the projectile simply a timer that does damage at the precise time, and have the client update positions etc to interpolate from start position to _current_ enemy position so that it impacts at about the right sort of time, but yeah, doesn't always travel at a constant speed.
lots of ways to cheat. either by clients or by the programmer.

pvs is nice and fast, assuming it has already been decompressed that is, and assuming you already know the two leafs that you're trying to determine the pvs for too, of course. If you don't already know the two leafs/clusters (q1 vs q3) then you're going to need to walk the bsp tree to find the relevent leaf first anyway. Its basically the same price as pointcontents, so long as you only want the pvs from a single leaf (read: single point). You may need to cache this leaf separately from the regular 'fatpvs' or entleaf_t stuff, as for speed you want to keep things with a single point instead of paying for supporting boxes.
Decompressing the pvs takes more time. QuakeWorld has always stored the pvs decompressed in ram, demonstrating that this can easily be load-time.
the problem is more that the pvs is a rendering optimisation. it is not perfectly tight. if you go with pvs only, you will end up with monsters seeing around corners if the leaf their in extends beyond said corner. For every player that might be in the pvs, your monster will need to use traceline to verify that it is actually visible. Doing that clientside keeps things more scalable (and helps a bit when people lag because of networking overload), but yeah, cheats.
.