I would like to display the exit code of a command if it is not 0 on a
line of its own, followed by the prompt on the next line.

Is this possible?
I was able to come up with the following:
PROMPT="%0(?..%?)
%{$fg[green]%}%n@%m%{$reset_color%}:%~ %{$fg[red]%}%#%{$reset_color%} "

However, this prints a newline after every command. Is there some
equivalent of '\n' that can be used inside the conditional substring?
Or some other way to do this?

Just put the portion that you want to be conditional inside the parens:
You had:
PROMPT="%0(?..%?)
%{$fg[green]%}%n@%m%{$reset_color%}:%~ %{$fg[red]%}%#%{$reset_color%} "
Instead use:
PROMPT="%0(?..%?
)%{$fg[green]%}%n@%m%{$reset_color%}:%~ %{$fg[red]%}%#%{$reset_color%} "
You also don't need the '0' in '%0', since it's the default, so:
PROMPT="%(?..%?
)%{$fg[green]%}%n@%m%{$reset_color%}:%~ %{$fg[red]%}%#%{$reset_color%} "
Adding in my personal preferences, and the following facts:
1. I prefer $''-style quoting when newlines are involved.
2. Parameter expansion is handled as part of prompt expansion.
3. The lone number sitting on a line by itself seems weird.
I might use:
PROMPT=$'%(?..%{$fg[red]%}error=%?%{$reset_color%}\n)%{$fg[green]%}%n@%m%{$reset_color%}:%~ %{$fg[red]%}%#%{$reset_color%} '
--
Best,
Ben