"This is because by the time the dependency or RDD goes out of scope, the stage will already have been removed."

Right, but do be aware that it doesn't work the other way around.  A stage and stageId can be created and associated with a ShuffleDependency when a job runs, then that stage and stageId can disappear from the DAGScheduler when the job completes (finished, canceled or aborted); but metadata, cached data, etc. for the associated ShuffleDependency should stick around as long as that ShuffleDependency is in scope, since DAGScheduler#newOrUsedStage will want to make use of prior mapOutputs (now associated with a fresh stageId) when it can instead of forcing re-evaluation of those results.

Just because one job and stage is done with a shuffleDep, and as long as that shuffleDep is in scope from some RDD, that doesn't me that another job will not want to make use of that shuffleDep.