Here is one solution that works, but I am not sure I would use elegant to describe it. It involves creating a scoreboard objective to create an inversion. First the score is set to 1 for a fake player and then an execute command resets the score. If no tagged entities exist, the score does not get reset. Then you can test for the score.
Create a dummy objective:
/scoreboard objectives add Invert dummy
Create a Repeat Unconditional Always Active command block with command:
scoreboard players set FakePlayer Invert 1
Follow with a Chain Unconditional Always Active command block with command:
execute @e[tag=summoned] ~ ~ ~ scoreboard players reset FakePlayer Invert
Create another Repeat Unconditional Always Active command block with command:
scoreboard players test FakePlayer Invert 1
Follow that with a Chain Conditional Always Active command block. This block is used to run whatever commands you want after the entities have all been killed. Note: this command will run repeatedly unless you stop the system.
Also, if you don't mind having an extra armor stand to store data as part of your system, you could use a scoreboard tag instead of adding an objective.