The definition of \PassOptionsToPackage is
% latex.ltx, line 7784:
\def\PassOptionsToPackage{\@pass@ptions\@pkgextension}
and we can look at \@pass@ptions:
% latex.ltx, line 7778:
\def\@pass@ptions#1#2#3{%
\expandafter\xdef\csname opt@#3.#1\endcsname{%
\@ifundefined{opt@#3.#1}\@empty
{\csname opt@#3.#1\endcsname,}%
\zap@space#2 \@empty}}
Suppose we call \PassOptionsToPackage{baz}{foo}. If \opt@foo.sty (can only be formed with \csname) is undefined, it is defined to expand to baz. If it is already defined, say to gnu,gnat, then it will be redefined to expand to gnu,gnat,baz.
The latter case can happen either if \PassOptionsToPackage{...}{foo} has already been called or the package has already been loaded. In the second case \PassOptionsToPackage{baz}{foo} does nothing.
As you see, new sets of options are chained to the already existing ones. It's then a job of the package, when loaded, to make its way amongst them.
This should also answer your question about detection: you can use
\ifcsname opt@foo.sty\endcsname
<options have already been passed or the package has already been loaded>
\else
<no options have been passed yet>
\fi