I think your idea is good: create a function that hook 'show_user_profile' and 'edit_user_profile' action. In this function use a conditional to show a textarea only for admins and the content of this textarea (saved as user meta) to the owner of the profile.
Something like (very rough and untested):
function custom_profile_content ( $user ) {
if ( current_user_can('edit_users') ) {
echo '<table class="form-table">';
$now = get_user_meta( $user->ID, 'custom_user_content', true ) ? : "";
printf( '<tr><th><label for="custom_user_content">%s</label></th>', esc_html__('Custom User Content', 'yourtextdomain') );
printf('<td><textarea name="custom_user_content" id="custom_user_content" rows="4" class="large-text" />%s</textarea></td></tr>', esc_textarea($now) );
echo '</table>';
} elseif( $user->ID == wp_get_current_user()->ID ) {
echo '<h3>' . __('Hi, there', 'yourtextdomain') . '</h3>';
echo '<p>' . $now . '</p>';
}
}
function custom_profile_content_save ( $user_id ) {
if ( isset($_POST['custom_user_content']) ) update_user_meta( $user_id, 'custom_user_content', $_POST['custom_user_content'] );
}
add_action( 'show_user_profile', 'custom_profile_content' );
add_action( 'edit_user_profile', 'custom_profile_content' );
add_action( 'personal_options_update', 'custom_profile_content_save' );
add_action( 'edit_user_profile_update', 'custom_profile_content_save' );