You need to do a quick SQL query to retrieve all authors, then run query_posts to generate a separate post loop on each one. This would replace The Loop presently in your index.php:
<?php
global $wpdb;
$authors = $wpdb->get_col("SELECT ID FROM $wpdb->users WHERE user_level > 0");
foreach($authors as $author) :
query_posts("author=$author&showposts=1");
if(have_posts()) the_post();
?>
<h3>Latest post from <?php the_author(); ?></h3>
Place regular “Loop” tags and elements here.
Read all posts by <?php the_author_posts_link(); ?>
<?php
endif;
endforeach;
?>
Note for WordPress 2.0 (and so on):
Performing the query as above on $authors in 2.0 will be a bit more complicated. We need to query a different table (wp_usermeta), but mainly the issue is what represents an “author”. Users receive ‘roles’ in 2.0, and these run by default from subscriber (equivalent to level 0 (Registered User) in 1.5 and below) to contributor, author, editor and finally administrator.
It’s possible all roles above subscriber on your blog will be considered “authors”. Or perhaps only contributor and author, or some other combination of the various roles. But in any case it’s something that needs to be accounted for (correctly) in the query. In the replacement example below, all roles (above subscriber) are matched in the meta_value column’s array by using the REGEXP comparison operator:
$authors = $wpdb->get_col("SELECT user_id FROM $wpdb->usermeta WHERE meta_key = 'wp_capabilities' AND meta_value REGEXP \"contributor|author|editor|administrator\"");
(Slashes in code above intended)
To remove one or more roles from the query, make sure to remove the accompanying separator (bar: | ).