¡Madre mía, qué follón de código...!
Si usas el módulo CGI, ¿por qué usas print() para sacar código HTTP/HTML?
¿Por qué importas dos veces el código CGI?
Vamos, que te sobran la mitad de las líneas...
Por favor, no pongas pantallazos del código, sino el propio código. Es más fácil luego de manejar (y ocupa bastante menos en disco).
En cuanto al tema de las tildes...
Supongamos que la base de datos almacena los datos en UTF-8, como comentas... entonces... los datos que pasan al programa Perl siguen estando en UTF-8... y por la primera pantalla veo que los caracteres salen como UTF-8 (los famosos caracteres 'Ãx'). PERO también hay párrafos que salen bien (MARÍA DE LOS ÁNGELES). Eso quiere decir que el programa Perl está emitiendo los textos sin realizar ninguna transformación ni codificación. Si, como supongo, el navegador web está usando la codificación ISO-8859-1 por defecto, entonces vemos mal los caracteres tildados en UTF-8, pero bien los textos que están codificados en ISO-8859-1 (o similar).
Al ponerle la cabecera para indicar que sí es un flujo UTF-8, cambian las tornas: salen bien los que antes salían mal, y viceversa.
Entonces... la solución es decodificar SIEMPRE lo que recibimos (la entrada estándar, los datos de la base de datos), y codificar SIEMPRE lo que sacamos hacia el navegador.
La recomendación actual es siempre usar el módulo Encode, para realizar las transformaciones. Y si un archivo o entrada estándar sabemos que está en una determinada codificación, usaremos
alguna capa E/S que haga la transformación de forma automática.