When does WordPress wrap inline scripts in CDATA?

Actually, it is not WordPress that is inserting the CDATA tags, but the visual editor, TinyMCE. Details of TinyMCE are offtopic here, but you can read a solution to this on Stackoverflow.

That said, stopping TinyMCE may not be the full solution you want. WordPress itself also has a function for adding CDATA tags, wxr_cdata, which is used when outputting a valid xml-file, for instance if you want to export the file of use the content in a rss-feed. Themes and/or plugins could decide to attach this filter to the content if they want the document to be valid xhtml.

This is where you then run into the bug, which was first documented twelve years ago and remains unsolved. It’s about these three lines in the_content:

$content = apply_filters( 'the_content', $content );
$content = str_replace( ']]>', ']]>', $content );
echo $content;

As you can see, the str_replace is hardcoded, immediately followed by the echo. There’s no way to intercept this replacement.

What you can do, however, if you control your theme, is buffer the_content and reverse the replacement. Like this:

ob_start();
the_content();
$content = ob_get_clean();
$content = str_replace( ']]&gt', ']]>', $content ); 
echo $content;