Second foreach in the loop returns bool(false) though array is present

As already pointed out by mrwweb and I quote from him

…but I don’t see any reason for any of your calls to setup_postdata() and wp_reset_postdata()

You are not trying to setup new posts here, just retrieving existing data from within the post which is already setup

The main reason for your problem is the use of the variable $post in all of your foreach loops. This creates a clash in the foreach loop following the previous one as the $post reference still remains after the foreach loop, thus the unexpected output. Here is what the php manual have to say

Warning

Reference of a $value and the last array element remain even after the foreach loop. It is recommended to destroy it by unset().

So, as possible solutions, you can either rename the $post variable to be unique in every foreach loop, or as recommended, unset($post) after each foreach.

Just on a side note, do not use : and endforeach, rather use curly brackets ({}). Curly brackets makes your code easier to debug and to read, and curly brackets are supported by all code editors, where as your method is not

EDIT

As explained, you should remove wp_reset_postdata() and setup_postdata() from you two foreach loops that is inside the main foreach loop. I have also totally rearranged your code. You have to check if your array_expression is not empty before the foreach and wrap that whole foreach loop in that conditional statement.

There is also absolutely no use in checking if $value is empty inside the foreach loop, it will always have a value for as long as there is something inside your array_expression. If your array_expression is empty, you will get the following error regardless if you check if Svalue is not empty

Warning: Invalid argument supplied for foreach()

This is how your code should look like (PLEASE NOTE: this is untested)

<?php

$all= get_posts(array('post_type' => 'books', 'numberposts' => -1,));
echo "VAR_DUMP(all) <br>";
var_dump($all);
echo "<br>";
echo "<br>";


if( !empty( $all ) ) {

foreach ( $all as $post ){

    setup_postdata($post);

     $booklink = array();

     $booklist = get_field('booklist'); 

          if( !empty($booklist) ) {
               foreach ($booklist as $bookpost) { 
                    

                  $booklink[] = strip_tags(get_field('booklink',$bookpost)); 
                                  
 
               }

             unset($bookpost);
          }


    echo "<br>";
    echo "var dump for booklist";
    echo "<br>";
    var_dump( $booklist);
    echo "<br>";
    echo "<br>";
     echo "booklink is - " . $booklink[0]."<br>";  

     $authorname = array();

     $authorlist = get_field('authorlist'); 

           if (!empty($authorlist)) {

               foreach ($authorlist as $authorpost) {


                        $authorname[] = strip_tags(get_field('authorname',$authorpost));                                       

                }
               
                unset($authorpost);

            }


    echo "<br>";
    echo "var dump for authorlist";
   echo "<br>";
    var_dump( $authorlist);
    echo "<br>";
   echo "<br>"; 
     echo "authorname is - ".$authorname[0]."<br>"; 


}
wp_reset_postdata();
unset($post);
}
?>