Yeah, this shows the limitations of creating a PDO wrapper. It makes it difficult to get rid of the foreach loop. Your wrapper is quite simple though, so I'll ignore it for now and use plain PDO.
The problem here is that you need a variable amount of placeholders in your query depending on how many entries there are in $prdt_sku. I solved this by using ? placeholders, like this:
public function deleteProducts(PDO $pdoHandle, array $products_sku)
{
    try {
        // put the right amount of placeholders in the query
        $query = "DELETE FROM products WHERE product_sku IN (" . 
                  trim(str_repeat(",?", count($products_sku)), ",") . ")";
        $statement = $pdoHandle->prepare($query);
        return $statement->execute($products_sku);
    } catch (Throwable $e) {
        echo 'Error deleting products from database. Redirecting...';
        header("HTTP/1.1 406 Error deleting product from database");
        header("refresh:3;url=https://metwesh.github.io/scandiweb-product-page/add-product");
    }
}
Note that this function now deletes multiple products. Here the assumption is that your "payload" is:
$products_sku = ["BOOK0002", "BOOK0003"];
It is actually not so difficult to use your wrapper for this. All that is needed is a small change to your execute() method. Like this:
public function execute($parameters = null)
{
    return $this->stmt->execute($parameters);
}
Then the deleteProduct() method can become this:
public function deleteProduct(array $products_sku)
{
    try {
        // put the right amount of placeholders in the query
        $query = "DELETE FROM products WHERE product_sku IN (" . 
                  trim(str_repeat(",?", count($products_sku)), ",") . ")";
        $this->db->query($query);
        return $this->db->execute($products_sku);
    } catch (Throwable $e) {
        echo 'Error deleting product from database. Reirecting...';
        header("HTTP/1.1 406 Error deleting product from database");
        header("refresh:3;url=https://metwesh.github.io/scandiweb-product-page/add-product");
    }
}
Some notes:
I really don't like variable names like $prdt_sku. Try to pronounce that! Most people would know what a "sku" is, so that's an acceptable abbreviation, but why do you use "prdt"? It must stand for "product", but would $product_sku be so bad? Please don't abbreviate unnecessarily. It's not faster, you don't safe memory space, all you do is make your code harder to read. Do you want that?
I cringe a bit at the way you handle the exception. You print an error and then jump out of the method and load another URL after 3 seconds. That's quite inflexible. You can never handle this exception in any other way. The method also doesn't return anything. Why not do:
public function deleteProduct(array $products_sku)
{
    try {
        // put the right amount of placeholders in the query
        $query = "DELETE FROM products WHERE product_sku IN (" . 
                  trim(str_repeat(",?", count($products_sku)), ",") . ")";
        $this->db->query($query);
        return $this->db->execute($products_sku);
    } catch (Throwable $e) {
        <.... store reason of exception ....>
        return false;
    }
    return true;
}
Then the calling code can still decide what to do with any failures. I would also store the reason for the exception somewhere in the class, so you can actually tell what happened. Note that the PDO statement does something similar with PDOStatement::errorInfo().