Replacing echo with return doesn’t work because your function is immediately terminated once it hits a return. See PHP docs for return.
It would be helpful to see your actual code, but the general concept within your shortcode function would be:
$output=""; // initialize output
while( $your_shortcode_query->have_posts() ):
$your_shortcode_query->the_post();
$foo = get_the_title();
$bar = get_permalink();
$output .= '<a href="'.$bar.'">'.$foo.'</a>'; // add to output
endwhile;
wp_reset_query();
return $output; // return output