You can run a foreach loop through all your categories then run a query for the latest posts in each category. You can do this by setting your home page to a static page then put this in a custom template. This is just a basic example:
$categories = get_the_categories();
foreach ( $categories as $cat ) {
$exclude = isset( $GLOBALS['current_id'] ) ? $GLOBALS['current_id'] : null;
$args = array(
'cat' => $cat->term_id,
'posts_per_page' => 4,
'post__not_in' => array( $exclude ),
'no_found_rows' => true,
);
echo '<h3>'. $cat->name . '</h3>';
$home_q = new WP_Query( $args );
while ( $home_q->have_posts() ) : $home_q->the_post();
$GLOBALS['current_id'] = get_the_ID();
// Do loop stuff here......
endwhile; wp_reset_postdata();
}
The $GLOBALS['current_id']
will hold an array of post ids to use in each additional query to prevent a post from showing up more than 1 time if it’s in multiple categories. Setting ‘no_found_rows` to true will make the query less taxing by not getting all the posts for pagination and stuff.