DLLFunc_Spawn works perfectly for me, as long as I use the following first:
set_pev(id, pev_flags, pev(id, pev_flags) | FL_FROZEN)
It seems that sometimes (maybe 1-2% of the time?) they can stay frozen after they spawn, so you could follow it with:
set_pev(id, pev_flags, pev(id, pev_flags) & ~FL_FROZEN)
 This also needs something like a 0.2 second delay between setting the flags and respawning them.
I can't come up with any explanation for why you have to freeze them (I found this in another thread), but there you have it. I'm not saying it's a better method either, since DLLFunc_Think needs less lines, but it was just to show it's possible.
They spawn with all their default weapons, the HUD, and no ghost corpses that I can see. The only exception is that if spectator is the first team you join when connecting to a server, when you respawn you won't have a HUD until you give yourself an item_suit. After that it sticks.