(Answering the “Where is the flaw in my reasoning?” part for understanding…)
Debugging
First, let's debug what's going on. Your MWE defines a \newenvironment, which does one thing or another based on the \newif called \if@show. In the example, the error comes from the “false” path, so we can specialize the MWE to consider just that part (and also leave out all the catcode and \ignorespaces stuff, for simplicity). So your MWE is further minimized to:
\documentclass{article}
\def\notToShow#1{}
\newenvironment{ToShowOrNotToShow}{%
\notToShow\bgroup%
}%
{%
\egroup%
}
\begin{document}
Normal text
\begin{ToShowOrNotToShow}
Text that is not necessarily shown.
\end{ToShowOrNotToShow}
Rest
\end{document}
which exhibits the same error as in the question. Going further, we can actually do what we imagine \newenvironment does, namely put its two arguments before and after the stuff that goes inside when the environment is used. (This is exactly what you did in the question where you wrote “I would expect this to expand to…”.) So:
\documentclass{article}
\def\notToShow#1{}
\begin{document}
Normal text
\notToShow\bgroup
Text that is not necessarily shown.
\egroup
Rest
\end{document}
Now the error is slightly different (if we're interested we can come back later to why the error is different), but an error nevertheless:
! Too many }'s.
l.7 \egroup
It may be already clear what the error is, but if not you can add:
\tracingonline=1
\tracingmacros=1
(or just \tracingall and search in the profuse output) to see, in the TeX output:
\notToShow #1->
#1<-\bgroup
which shows what's happening: the macro \notToShow gets the token \bgroup as its argument (#1), and then (per its definition) replaces the token with nothing. Later, when the \egroup is encountered, it does not correspond to any earlier \bgroup (recall that \notToShow consumed the token), which explains the error.
Advice
After learning a little bit about TeX and writing macros and all that, I find there's a trick to it that seems to help. The trick is to not start writing out the definition of a macro, the way you would when writing say a function in another language. Instead, recall that macros are simply text (or token) substitution (i.e. they work by expansion), and write out the expanded part first. Make sure it works. Only then start writing the macros, purely as a shortcut to avoid typing out the whole thing each time. (That was after all the original purpose of including the feature in TeX.)
(Actually the even bigger lesson I learned is to avoid writing macros at all if possible, and instead do text processing in an external program or LuaTeX callbacks….)
In this case, if you started with the fully expanded out
\toShow\bgroup
Text that is not necessarily shown.
\egroup
and
\notToShow\bgroup
Text that is not necessarily shown.
\egroup
(for the if and else cases respectively), you would have already encountered an issue in the else case. (You don't encounter an issue in the if case because \def\toShow#1{#1} applied to \bgroup (not as intended) simply puts back \bgroup, so the \egroup is not unexpected.)
Solution
For macro expansion, instead of invoking the macro with \foo {bar}, you cannot write \foo \bgroup bar\egroup. TeX doesn't work like that; it looks for an explicit { or for any character with that catcode (1). (In fact, if it allowed \bgroup and \egroup here, then that would defeat their purpose, and you could just directly write { or } everywhere.)
But \bgroup and \egroup work for many other TeX primitives, and one that you can use here (as suggested in the comments) is \vbox.
So, to write the macro, first verify that you have what you want, when fully expanded out:
\documentclass{article}
\begin{document}
% To show the text, just insert it into a vbox.
Normal text
\vbox\bgroup
Text that is not necessarily shown.
\egroup
Rest
% To hide the text, assign to box 0 and don't use it.
Normal text
\setbox0\vbox\bgroup
Text that is not necessarily shown.
\egroup
Rest
\end{document}

(Actually this does not look desirable, but it more or less matches what you said in the other answer with “This does what I want it to do”. I'm dropping the “Behold” and the \ignorespaces etc. for simplicity, but imagine you have the appropriate things here.)
Next introduce the \ifs:
\documentclass{article}
\begin{document}
\newif\ifshow
\showtrue % Try with and without this
Normal text
\ifshow
\vbox\bgroup
\else
\setbox0\vbox\bgroup
\fi
Text that is not necessarily shown.
\egroup
Rest
\end{document}
Finally, only once you're satisfied, define your environment:
\documentclass{article}
\newif\ifshow
\newenvironment{ToShowOrNotToShow}{%
\ifshow
\vbox\bgroup
\else
\setbox0\vbox\bgroup
\fi
}{%
\egroup
}
\begin{document}
\showtrue % Try with and without this
Normal text
\begin{ToShowOrNotToShow}
Text that is not necessarily shown.
\end{ToShowOrNotToShow}
Rest
\end{document}
and here you can add the \ignorespacesafterend and other stuff specific to LaTeX environments.
solution-environment of theexam-package is defined using\bgroup/\egroup. How come it works there? – gebruiker Jan 16 '18 at 10:51\bgroupand\egroupare only equivalent to{and}when it comes to plainTeX boxes. This is because the boxed content is processed while collected and not just collected as with macro arguments. In order for your code to work you need to define\not@to@showto be a savebox command which then discards the content. – Martin Scharrer Jan 16 '18 at 11:03\def\not@to@show{\adjustbox{discard}}would do the trick, as it reads its 'argument' as box. (Needsadjustboxpackage, addvarwidth=\linewidthas first argument if you have paragraph content). You need something similar for\to@show. – Martin Scharrer Jan 16 '18 at 11:05