\selectlanguage pushes section to new page

Your guess is right. At the end of \end{itemize}, an instruction

\addvspace{<skip 1>}

is issued and \section issues

\addvspace{<skip 2>}

so, in normal situations, only the greater skip results in the output. However, as you observe, the \write instruction that's part of \selectlanguage makes it impossible for the second \addvspace to know the amount of <skip 1>, because the last item in the vertical list is no longer a vertical skip.

You can manually fix this with

\setlength{\skip0}{\lastskip}
\addvspace{-\skip0}
\selectlanguage{ngerman}
\addvspace{\skip0}

which works for the particular situation.

Output without the four above lines

Note the correct English hyphenation of “representation”.

enter image description here

Output with the four lines above

Note the incorrect English hyphenation of “representation” (due to using German hyphenation rules).

enter image description here


hyperref tries quite hard to avoid such side effects. You could steal its commands:

\documentclass{article}

\usepackage{kantlipsum}
\usepackage[ngerman,english]{babel}
\usepackage{hyperref}
\begin{document}
\section{Foo}
\kant[1]
\begin{itemize}
\item
\item
\item
\item
\item
\end{itemize}
\kant[2]
\begin{itemize}
\item
\item
\item
\item
\end{itemize}


\makeatletter
\Hy@SaveLastskip
\selectlanguage{english}
\Hy@RestoreLastskip
\makeatother


\section{Baz}

\kant[1]

\end{document}

(It is not perfect, in some cases it then suppress a break point).