Para hacer esto es necesario que guardes algún valor en la tabla usuario que indique cual es el último mensaje (o fecha) que ha leído para luego poder filtrar y mostrar solo lo más reciente.
Supongamos que ese valor es un campo llamado "FechaUltimoMensaje" en la tabla usuario por lo que, para mostrar los mensajes no vistos para dicho usuario no bastaría con hacer un inner join entre ambas tablas:
SELECT mensajes.* FROM mensajes INNER JOIN usuarios
ON usuarios.FechaUltimoMensaje < mensajes.Fecha
WHERE usuarios.Id = 'id del usuario actual'
ORDER BY mensajes. Fecha
De este modo, sin modificar la tabla de Mensajes, puedes tener un puntero único por cada usuario de tu sistema que le indique que mensajes ha leído ya y, por lo tanto, cuales tiene por leer.