I forgot I even asked this question, but since I figured it out I thought I might as well share the way I did it.
So, the way I ended up doing this isn't as clean as I had wanted it to be (I was hoping I could avoid redstone and use just command blocks), but it works so I don't care too much.
Before the game starts, everyone who is playing the game is added to a team, which can be named anything but for the purposes of this I'll just call it "gameplayers." When said person dies, they respawn inside of a small holding chamber.
There's a repeating command block with the following command inside of it to remove them from the team:
/scoreboard teams leave gameplayers @p[r=8]
You can probably use "@a" for this as well.
Then, I have another repeating command block nearby with the following command:
/testfor @a[r=300,team=gameplayers]
The "r=300" is the radius from the command block that the players might be in. If you want to specify a cubic area rather than a spherical one, you can also use the "x" "y" and "z" arguments alongside the "dx" "dy" and "dz" arguments.
From there, I have a comparator facing out of the command block (in the default state). This goes into 2 pieces of redstone, and the second piece of restone has a restone torch attached to the side of the block it rests on.
The reason this works is because the repeating command block outputs a redstone strength to the comparator equal to the number of players matching the given arguments. So, when there are 2 or more players left, both pieces of redstone will remain lit, and the torch will remain off. When there is just 1 player remaining, the strength of the comparator output is reduced to 1 and the second piece of redstone turns off, enabling the redstone torch. You can take output from this torch to run commands to cleanup after the game has ended.
I hope this helped someone :)